package com.kordar.rbac;

import java.util.Map;
import java.util.Set;

public interface AuthManager extends CheckAccess {
    /**
     * Creates a new Role object.
     * Note that the newly created role is not added to the RBAC system yet.
     * You must fill in the needed data and call [[add()]] to add it to the system.
     *
     * @param name String the role name
     * @return Role the new Role object
     */
    Role createRole(String name);

    /**
     * Creates a new Permission object.
     * Note that the newly created permission is not added to the RBAC system yet.
     * You must fill in the needed data and call [[add()]] to add it to the system.
     *
     * @param name String the permission name
     * @return Permission the new Permission object
     */
    Permission createPermission(String name);

    /**
     * Adds a role, permission or rule to the RBAC system.
     *
     * @param object Permission|Rule $object
     * @return bool whether the role, permission or rule is successfully added to the system
     */
    boolean add(Item object);

    boolean add(Rule rule);

    /**
     * Removes a role, permission or rule from the RBAC system.
     *
     * @param object Role|Permission|Rule
     * @return bool whether the role, permission or rule is successfully removed
     */
    boolean remove(Item object);

    boolean remove(Rule rule);

    /**
     * Updates the specified role, permission or rule in the system.
     *
     * @param name   string $ the old name of the role, permission or rule
     * @param object Role|Permission|Rule $
     * @return bool whether the update is successful
     */
    boolean update(String name, Item object);

    boolean update(String name, Rule rule);

    /**
     * Returns the named role.
     *
     * @param name string $ the role name.
     * @return null|Role the role corresponding to the specified name. Null is returned if no such role.
     */
    Role getRole(String name);

    /**
     * Returns all roles in the system.
     *
     * @return Role[] all roles in the system. The array is indexed by the role names.
     */
    Set<Role> getRoles();

    /**
     * Returns the roles that are assigned to the user via [[assign()]].
     * Note that child roles that are not assigned directly to the user will not be returned.
     *
     * @param userId string|int $ the user ID (see [[\yii\web\User::id]])
     * @return Role[] all roles directly assigned to the user. The array is indexed by the role names.
     */
    Set<Role> getRolesByUser(Long userId);

    /**
     * Returns child roles of the role specified. Depth isn't limited.
     *
     * @param roleName string $ name of the role to file child roles for
     * @return Role[] Child roles. The array is indexed by the role names.
     * First element is an instance of the parent Role itself.
     */
    Set<Role> getChildRoles(String roleName);

    /**
     * Returns the named permission.
     *
     * @param name string $ the permission name.
     * @return null|Permission the permission corresponding to the specified name. Null is returned if no such permission.
     */
    Permission getPermission(String name);

    /**
     * Returns all permissions in the system.
     *
     * @return Permission[] all permissions in the system. The array is indexed by the permission names.
     */
    Set<Permission> getPermissions();

    /**
     * Returns all permissions that the specified role represents.
     *
     * @param roleName string $ the role name
     * @return Permission[] all permissions that the role represents. The array is indexed by the permission names.
     */
    Set<Permission> getPermissionsByRole(String roleName);

    /**
     * Returns all permissions that the user has.
     *
     * @param userId string|int $ the user ID (see [[\yii\web\User::id]])
     * @return Permission[] all permissions that the user has. The array is indexed by the permission names.
     */
    Set<Permission> getPermissionsByUser(Long userId);

    /**
     * Returns the rule of the specified name.
     *
     * @param name string $ the rule name
     * @return null|Rule the rule object, or null if the specified name does not correspond to a rule.
     */
    Rule getRule(String name);

    /**
     * Returns all rules available in the system.
     *
     * @return Rule[] the rules indexed by the rule names
     */
    Map<String, Rule> getRules();

    /**
     * Checks the possibility of adding a child to parent.
     *
     * @param parent Item $ the parent item
     * @param child  Item $ the child item to be added to the hierarchy
     * @return bool possibility of adding
     * @since 2.0.8
     */
    boolean canAddChild(Item parent, Item child);

    /**
     * Adds an item as a child of another item.
     *
     * @param parent Item $
     * @param child  Item $
     * @return bool whether the child successfully added
     */
    boolean addChild(Item parent, Item child);

    /**
     * Removes a child from its parent.
     * Note, the child item is not deleted. Only the parent-child relationship is removed.
     *
     * @param parent Item $
     * @param child  Item $
     * @return bool whether the removal is successful
     */
    boolean removeChild(Item parent, Item child);

    /**
     * Removed all children form their parent.
     * Note, the children items are not deleted. Only the parent-child relationships are removed.
     *
     * @param parent Item $
     * @return bool whether the removal is successful
     */
    boolean removeChildren(Item parent);

    /**
     * Returns a value indicating whether the child already exists for the parent.
     *
     * @param parent Item $
     * @param child  Item $
     * @return bool whether `$child` is already a child of `$parent`
     */
    boolean hasChild(Item parent, Item child);

    /**
     * Returns the child permissions and/or roles.
     *
     * @param name string $ the parent name
     * @return Item[] the child permissions and/or roles
     */
    Set<Item> getChildren(String name);

    /**
     * Assigns a role to a user.
     *
     * @param item   Role|Permission $
     * @param userId string|int $ the user ID (see [[\yii\web\User::id]])
     * @return Assignment the role assignment information.
     */
    Assignment assign(Item item, Long userId);

    /**
     * Revokes a role from a user.
     *
     * @param item   Role|Permission $
     * @param userId string|int $ the user ID (see [[\yii\web\User::id]])
     * @return bool whether the revoking is successful
     */
    boolean revoke(Item item, Long userId);

    /**
     * Revokes all roles from a user.
     *
     * @param userId mixed $ the user ID (see [[\yii\web\User::id]])
     * @return bool whether the revoking is successful
     */
    boolean revokeAll(Long userId);

    /**
     * Returns the assignment information regarding a role and a user.
     *
     * @param roleName string $ the role name
     * @param userId   string|int $ the user ID (see [[\yii\web\User::id]])
     * @return null|Assignment the assignment information. Null is returned if
     * the role is not assigned to the user.
     */
    Assignment getAssignment(String roleName, Long userId);

    /**
     * Returns all role assignment information for the specified user.
     *
     * @param userId string|int $ the user ID (see [[\yii\web\User::id]])
     * @return Assignment[] the assignments indexed by role names. An empty array will be
     * returned if there is no role assigned to the user.
     */
    Map<String, Assignment> getAssignments(Long userId);

    /**
     * Returns all user IDs assigned to the role specified.
     *
     * @param roleName string $
     * @return array array of user ID strings
     * @since 2.0.7
     */
    Set<Long> getUserIdsByRole(String roleName);

    /**
     * Removes all authorization data, including roles, permissions, rules, and assignments.
     */
    void removeAll();

    /**
     * Removes all permissions.
     * All parent child relations will be adjusted accordingly.
     */
    void removeAllPermissions();

    /**
     * Removes all roles.
     * All parent child relations will be adjusted accordingly.
     */
    void removeAllRoles();

    /**
     * Removes all rules.
     * All roles and permissions which have rules will be adjusted accordingly.
     */
    void removeAllRules();

    /**
     * Removes all role assignments.
     */
    void removeAllAssignments();
}
